package me.shurufa.net;

import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.kaopiz.kprogresshud.KProgressHUD;

import me.shurufa.activities.BaseActivity;
import me.shurufa.utils.Global;
import me.shurufa.utils.Utils;

/**
 * Created by yao on 15/7/23.
 */
public abstract class RequestServerTask<T extends BaseResponse>
    extends AsyncTask<Void, Void, String> {
  private static final String LOG_TAG = RequestServerTask.class.getSimpleName();
  public static final String ERR_MSG = "网络连接失败";
  String default_err_msg;
  Class<T> responseType;
  String progressTitle;
  BaseActivity mActivity;
  Fragment mFragment;
  View viewForSnackbar;
  String errorType;
  private KProgressHUD kProgressHUD;

  public RequestServerTask(Class<T> responseType) {
    super();
    this.responseType = responseType;
  }

  public RequestServerTask(Class<T> responseType, Object parent, String progressTitle) {
    super();
    this.responseType = responseType;
    if (parent instanceof BaseActivity) {
      mActivity = (BaseActivity) parent;
    } else if (parent instanceof Fragment) {
      mFragment = (Fragment) parent;
    }
    this.progressTitle = progressTitle;
  }

  public RequestServerTask setDefaultErrMsg(String errMsg) {
    this.default_err_msg = errMsg;
    return this;
  }

  public RequestServerTask setDefaultErrMsg(int errMsg) {
    this.default_err_msg = Global.getContext().getString(errMsg);
    return this;
  }

  public RequestServerTask setSnackbarView(View view) {
    this.viewForSnackbar = view;
    return this;
  }

  @Override
  protected String doInBackground(Void... params) {
    return requestServer();
  }

  protected abstract String requestServer();

  @Override
  protected void onPostExecute(String s) {
    super.onPostExecute(s);
    T result;
    try {
      if (s != null) {
        result = Global.getGson().fromJson(s, responseType);
      } else {
        result = null;
      }
      if (result != null && result.success) {
        onSuccess(result);
      } else {
        boolean handled = onFailure(result);
        if (!handled) {
          if (result != null && result.error!=null&&!TextUtils.isEmpty(result.error.message)) {
            // TODO result !=null has error message
            Utils.showToast(result.error.message);
          } else if (default_err_msg != null) {
            // result = null has set default error msg
            Utils.showToast(default_err_msg);
          } else {
            // result = null no set error msg
            Utils.showToast(ERR_MSG);
          }

        }
      }
    } catch (Exception e) {
      Log.e(LOG_TAG, Log.getStackTraceString(e));
    } finally {
      onFinish();
    }
  }

  protected abstract void onSuccess(T result);

  protected void onStart() {
    if (!TextUtils.isEmpty(progressTitle)) {
      if (mActivity != null) {
        kProgressHUD = KProgressHUD.create(mActivity);
        kProgressHUD.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
                .setLabel(progressTitle)
                .setCancellable(false)
                .setAnimationSpeed(2)
                .setDimAmount(0.5f)
                .show();
        // progressFragment = ProgressFragment.show(mActivity, progressTitle);
      } else if (mFragment != null) {
        // progressFragment = ProgressFragment.show(mFragment, progressTitle);
        kProgressHUD = KProgressHUD.create(mFragment.getActivity());
        kProgressHUD.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
                .setLabel(progressTitle)
                .setCancellable(false)
                .setAnimationSpeed(2)
                .setDimAmount(0.5f)
                .show();
      }
    }
  }

  protected void onFinish() {
    // if (progressFragment != null) {
    // progressFragment.dismissAllowingStateLoss();
    // progressFragment.dismiss();
    // progressFragment = null;
    // }
    if (kProgressHUD!=null){
      kProgressHUD.dismiss();
      kProgressHUD = null;
    }
  }

  protected boolean onFailure(final T result) {
    return false;
  }

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    onStart();
  }

  public void start() {
    this.executeOnExecutor(THREAD_POOL_EXECUTOR);
  }
}
